home *** CD-ROM | disk | FTP | other *** search
/ ...taking it to the Macs! / ...taking it to the Macs!.iso / Extras / ActiveX Mac SDK / ActiveX SDK / Container Common / CArgumentParser.cpp < prev    next >
Text File  |  1997-01-03  |  5KB  |  168 lines

  1. // ===========================================================================
  2. //    CArgumentParser.cpp               ©1996 Microsoft Corporation. All rights reserved.
  3. // ===========================================================================
  4.  
  5. #include "CArgumentParser.h"
  6.  
  7. CArgumentParser::CArgumentParser(void)
  8. {
  9.     Buffer = ::NewHandle(0);
  10.  
  11.     Reset();
  12. }
  13.  
  14. CArgumentParser::~CArgumentParser(void)
  15. {
  16.     ::DisposeHandle(Buffer);
  17. }
  18.  
  19. void CArgumentParser::Reset(void)
  20. {
  21.     ::SetHandleSize(Buffer, 0);
  22.     CurrentState = Stop;
  23.     InputBufferCount = 0;
  24. }
  25.  
  26. Boolean    CArgumentParser::ProcessChar(char c)
  27. {
  28.     //
  29.     //    parse tables
  30.     //
  31.     parseraction ActTable[] = {    /*    Alpha            Numeric            WhiteSpace        Assignment        Quote            Unknown            EOF    */
  32.         /*    WaitArgName        */        AddToBuffer,    Error,            None,            Error,            Error,            Error,            None,
  33.         /*    BuildArgName    */        AddToBuffer,    AddToBuffer,    TermArgName,    TermArgName,    Error,            Error,            Error,
  34.         /*    WaitAssign        */        Error,            Error,            None,            None,            Error,            Error,            Error,
  35.         /*    WaitArgValue    */        AddToBuffer,    AddToBuffer,    None,            Error,            None,            Error,            Error,
  36.         /*    BuildArgVal        */        AddToBuffer,    AddToBuffer,    TermArgValue,    Error,            Error,            Error,            TermArgValue,
  37.         /*    BuildArgValLit    */        AddToBuffer,    AddToBuffer,    AddToBuffer,    AddToBuffer,    TermArgValue,    AddToBuffer,    Error,
  38.         /*    Undefined        */        None,            None,            None,            None,            None,            None,            None
  39.     };
  40.  
  41.     parserstate    StateTable[] = {/*    Alpha            Numeric            WhiteSpace        Assignment        Quote            Unknown            EOF    */
  42.         /*    WaitArgName        */        BuildArgName,    Undefined,        WaitArgName,    Undefined,        Undefined,        Undefined,        Stop,
  43.         /*    BuildArgName    */        BuildArgName,    BuildArgName,    WaitAssign,        WaitArgValue,    Undefined,        Undefined,        Undefined,
  44.         /*    WaitAssign        */        Undefined,        Undefined,        WaitAssign,        WaitArgValue,    Undefined,        Undefined,        Undefined,
  45.         /*    WaitArgValue    */        BuildArgVal,    BuildArgVal,    WaitArgValue,    Undefined,        BuildArgValLit,    Undefined,        Undefined,
  46.         /*    BuildArgVal        */        BuildArgVal,    BuildArgVal,    WaitArgName,    Undefined,        Undefined,        Undefined,        Stop,
  47.         /*    BuildArgValLit    */        BuildArgValLit,    BuildArgValLit,    BuildArgValLit,    BuildArgValLit,    WaitArgName,    BuildArgValLit,    Undefined,
  48.         /*    Undefined        */        Undefined,        Undefined,        Undefined,        Undefined,        Undefined,        Undefined,        Undefined
  49.     };
  50.  
  51.     Int16        Index;
  52.  
  53.     //    find the index into the table based upon the input character's type
  54.     {
  55.         chartype    t;
  56.  
  57.         if ((c >= 'a' && c <='z') || (c >= 'A' && c <='Z'))
  58.             t = Alpha;
  59.         else if (c >= '0' && c <= '9')
  60.             t = Numeric;
  61.         else if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
  62.             t = WhiteSpace;
  63.         else if (c == '=')
  64.             t = Assignment;
  65.         else if (c == '\"')
  66.             t = Quote;
  67.         else if (c == '\0')
  68.             t = EOF;
  69.         else
  70.             t = Unknown;
  71.  
  72.         Index = CurrentState * CharTypeCount + t;
  73.     }
  74.  
  75.     //    do the action in the table and go to the next state
  76.     CurrentState = StateTable[Index];
  77.     switch (ActTable[Index])
  78.     {
  79.         case AddToBuffer:
  80.             *(InputBuffer + InputBufferCount++) = c;
  81.             break;
  82.         case TermArgName:
  83.         case TermArgValue:
  84.             {
  85.                 unsigned long    TotalBufferSize = ::GetHandleSize(Buffer);
  86.                 *(InputBuffer + InputBufferCount++) = '\0';
  87.                 ::SetHandleSize(Buffer,TotalBufferSize + InputBufferCount);
  88.                 ::BlockMove(InputBuffer, *Buffer + TotalBufferSize, InputBufferCount);
  89.                 InputBufferCount = 0;
  90.             }
  91.             break;
  92.         case None:
  93.             break;
  94.         case Error:
  95.         default:
  96.             break;
  97.     }
  98.  
  99.     return CurrentState != Undefined;
  100. }
  101.  
  102.  
  103. Boolean CArgumentParser::GetArguments(Ptr *pArgBuffer, char **pArgNames[], char **pArgValues[], short *pArgCount)
  104. {
  105.     Boolean    ReturnValue = true;
  106.  
  107.     if (CurrentState == Stop)
  108.     {
  109.         Int32    BufferSize = ::GetHandleSize(Buffer);
  110.         Ptr        ArgBuffer;
  111.         Int16    ArgCount;
  112.  
  113.         //    figure out how many arguments we have
  114.         {
  115.             Int16    i;
  116.             char    *p;
  117.  
  118.             for (i = 0, p = *Buffer + BufferSize; p >= *Buffer; p--)
  119.                 if (*p == '\0')
  120.                     i++;
  121.  
  122.             ArgCount = i / 2;
  123.         }
  124.  
  125.         //    allocate a buffer to hold all of our data
  126.         if ((ArgBuffer = ::NewPtr(BufferSize + ArgCount * 2 * sizeof(char *))) != NULL)
  127.         {
  128.             char    *here = ArgBuffer + ArgCount * 2 * sizeof(char *);
  129.             char    **ArgNames, **ArgValues;
  130.             Int16    i = ArgCount;
  131.  
  132.             ::BlockMove(*Buffer, ArgBuffer + ArgCount * 2 * sizeof(char *), BufferSize);
  133.             ArgNames = (char **)ArgBuffer;
  134.             ArgValues = (char **)ArgBuffer + ArgCount;
  135.  
  136.             while (i--)
  137.             {
  138.                 *ArgNames++ = here;
  139.                 while (*here++ != '\0')
  140.                     ;
  141.                 *ArgValues++ = here;
  142.                 while (*here++ != '\0')
  143.                     ;
  144.             }
  145.  
  146.             //    transfer out the pointers
  147.             *pArgBuffer = ArgBuffer;
  148.             *pArgCount = ArgCount;
  149.             *pArgNames = (char **)ArgBuffer;
  150.             *pArgValues = (char **)ArgBuffer + ArgCount;
  151.         }
  152.         else
  153.             ReturnValue = false;
  154.     }
  155.     else
  156.         ReturnValue = false;
  157.  
  158.     if (!ReturnValue)
  159.     {
  160.         *pArgBuffer = NULL;
  161.         *pArgCount = 0;
  162.         *pArgNames = NULL;
  163.         *pArgValues = NULL;
  164.     }
  165.  
  166.     return ReturnValue;
  167. }
  168.